import {Directive, ViewContainerRef, DynamicComponentLoader, ComponentRef, Provider,
    ReflectiveInjector, ElementRef} from "@angular/core";
import {PopoverContainer} from "./popover-container.component";
import {PopoverOptions} from "./popover.interface";

@Directive({
    selector: '[popover]',
    inputs: [
        'content: popover-content',
        'placement: popover-placement',
        'container: popover-container',
        'title: popover-title',
        'html: popover-html',
        'animation: popover-animation',
        'isOpen: popover-is-open'
    ],
    host: {
        //'(focusin)': 'show($event, $target)',
        //'(mouseenter)': 'show($event, $target)',
        //'(focusout)': 'hide($event, $target)',
        //'(mouseleave)': 'hide($event, $target)',
        '(click)': 'toggle($event, $target)'
    }
})
export class Popover {
    container: string = 'body';
    placement: string = 'top';
    content: string;
    title: string;
    html: boolean = false;
    animation: boolean = true;
    isOpen: boolean;

    element: ElementRef;
    loader: DynamicComponentLoader;
    cr: ViewContainerRef;

    private visible: boolean = false;
    private popover: Promise<ComponentRef<any>>;

    constructor(el: ElementRef, ld: DynamicComponentLoader, cr: ViewContainerRef) {
        this.element = el;
        this.loader = ld;
        this.cr = cr;
    }

    ngOnInit() {
        if (this.isOpen) {
            this.show();
        }
    }

    show(event?: any, target?: any) {
        if (this.visible) {
            return;
        }
        this.visible = true;

        let options = new PopoverOptions({
            title: this.title,
            content: this.content,
            placement: this.placement,
            animation: this.animation,
            hostEl: this.element,
            html: this.html,
            isOpen: this.isOpen
        });
        var binding = ReflectiveInjector.resolve([
            new Provider(PopoverOptions, {useValue: options})
        ]);

        this.popover = this.loader.loadNextToLocation(PopoverContainer, this.cr, binding)
            .then((componentRef: ComponentRef<any>) => {
                return componentRef;
        });
    }

    hide(event?: any, target?: any) {
        if (!this.visible) {
            return;
        }
        this.visible = false;

        this.popover.then((componentRef: ComponentRef<any>) => {
            componentRef.destroy();
            return componentRef;
        });
    }

    toggle(event?: any, target?: any) {
        if (this.visible) {
            this.hide();
        } else {
            this.show();
        }
    }

}
